<template>
  <div class="app-header">
    <div class="head-left">
      <t-dropdown>
        <a>
          <t-icon name="file" />
          <span>文件</span>
        </a>
        <t-dropdown-menu>
          <t-dropdown-item @click="newFile">
            <a>新建文件</a>
          </t-dropdown-item>
          <t-dropdown-item @click="openFile" divider="true">
            <a>打开文件</a>
          </t-dropdown-item>
          <t-dropdown-item @click="downloadJson" divider="true">
            <a>下载JSON文件</a>
          </t-dropdown-item>
          <t-dropdown-item @click="downloadPng">
            <a>下载为PNG</a>
          </t-dropdown-item>
          <t-dropdown-item @click="downloadSvg">
            <a>下载为SVG</a>
          </t-dropdown-item>
        </t-dropdown-menu>
      </t-dropdown>
      <t-dropdown>
        <a>
          <t-icon name="edit-1" />
          <span>编辑</span>
        </a>
        <t-dropdown-menu>
          <t-dropdown-item>
            <a @click="onUndo">
              <div class="flex">
                撤销 <span class="flex-grow"></span> Ctrl + Z
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item divider="true">
            <a @click="onRedo">
              <div class="flex">
                恢复 <span class="flex-grow"></span> Ctrl + Y
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item>
            <a @click="onCut">
              <div class="flex">
                剪切 <span class="flex-grow"></span> Ctrl + X
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item>
            <a @click="onCopy">
              <div class="flex">
                复制 <span class="flex-grow"></span> Ctrl + C
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item divider="true">
            <a @click="onPaste">
              <div class="flex">
                粘贴 <span class="flex-grow"></span> Ctrl + V
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item>
            <a @click="onAll">
              <div class="flex">
                全选 <span class="flex-grow"></span> Ctrl + A
              </div>
            </a>
          </t-dropdown-item>
          <t-dropdown-item>
            <a @click="onDelete">
              <div class="flex">删除 <span class="flex-grow"></span> DELETE</div>
            </a>
          </t-dropdown-item>
        </t-dropdown-menu>
      </t-dropdown>
      <a @click="onSave(true)">
        <t-icon name="save" />
        <span>保存</span>
      </a>
    </div>
    <div class="head-center">
      <a :class="[isOnDrawLine == true ? 'active' : '']" @click="onDrawLine">
        <t-icon name="pen" />
        <span>钢笔</span>
      </a>
      <a :class="[isDrawingPencil == true ? 'active' : '']" @click="onDrawingPencil">
        <t-icon name="edit" />
        <span>铅笔</span>
      </a>
      <a :class="[isShowMagnifier == true ? 'active' : '']" @click="onShowMagnifier">
        <t-icon name="search" />
        <span>放大镜</span>
      </a>
      <a @click="onUndo">
        <t-icon name="rollback" />
        <span>撤销</span>
      </a>
      <a @click="onRedo">
        <t-icon name="rollfront" />
        <span>重做</span>
      </a>
      <a @dragstart="onAddShape($event, 'line')" @click="onAddShape($event, 'line')">
        <t-icon name="remove" />
        <span>直线</span>
      </a>
      <a @dragstart="onAddShape($event, 'text')" @click="onAddShape($event, 'text')">
        <t-icon name="textbox" />
        <span>文字</span>
      </a>
      <a-dropdown :open="lineWidthVisible">
        <a style="line-height: 40px;">
          {{ data.lineWidth }}&nbsp;
          <span>线宽</span>
          <CaretDownOutlined />
        </a>
        <template #overlay>
          <a-menu style="width: 160px">
            <a-menu-item key="1">
              <a-input-number
                v-model:value="data.lineWidth"
                style="width: 100%"
                @blur="getDataLineWidth"
              />
            </a-menu-item>
          </a-menu>
        </template>
      </a-dropdown>
      <a-dropdown>
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                lineTypes.find((item) => item.value === currentLineType)?.icon
              "
            ></use>
          </svg>
          <span>连线</span>
          <CaretDownOutlined />
        </a>
        <template #overlay>
          <a-menu>
            <template v-for="(item, idx) in lineTypes" :key="idx">
              <a-menu-item>
                <div class="flex middle" @click="changeLineType(item.value)">
                  {{ item.name }} <span class="flex-grow"></span>
                  <svg class="l-icon" aria-hidden="true">
                    <use :xlink:href="item.icon"></use>
                  </svg>
                </div>
              </a-menu-item>
            </template>
          </a-menu>
        </template>
      </a-dropdown>
      <a-dropdown>
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                fromArrows.find((item) => item.value === fromArrow)?.icon
              "
            ></use>
          </svg>
          <span>起点</span>
          <CaretDownOutlined />
        </a>
        <template #overlay>
          <a-menu>
            <template v-for="(item, idx) in fromArrows" :key="idx">
              <a-menu-item>
                <div
                  class="flex middle"
                  style="height: 30px"
                  @click="changeFromArrow(item.value)"
                >
                  <svg class="l-icon" aria-hidden="true">
                    <use :xlink:href="item.icon"></use>
                  </svg>
                </div>
              </a-menu-item>
            </template>
          </a-menu>
        </template>
      </a-dropdown>
      <a-dropdown>
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                toArrows.find((item) => item.value === toArrow)?.icon
              "
            ></use>
          </svg>
          <span>终点</span>
          <CaretDownOutlined />
        </a>
        <template #overlay>
          <a-menu>
            <template v-for="(item, idx) in toArrows" :key="idx">
              <a-menu-item>
                <div
                  class="flex middle"
                  style="height: 30px"
                  @click="changeToArrow(item.value)"
                >
                  <svg class="l-icon" aria-hidden="true">
                    <use :xlink:href="item.icon"></use>
                  </svg>
                </div>
              </a-menu-item>
            </template>
          </a-menu>
        </template>
      </a-dropdown>
      <a
        class="iconfont icon-Anchorpoint"
        :class="[isAutoAnchor == true ? 'active' : '']"
        @click="onAutoAnchor"
      >
        <span>自动锚点</span>
      </a>
      <a
        class="iconfont icon-a-56px_line_Anti-fraud"
        :class="[isDisableAnchor == true ? 'active' : '']"
        @click="onDisableAnchor"
      >
        <span>
          {{ isDisableAnchor ? "显示锚点" : "禁用锚点" }}
        </span>
      </a>
    </div>
    <div class="head-right">
      <a
        @click="setLocked"
        :style="{
          color: data.locked == 1 ? '#faad14' : data.locked == 2 ? 'red' : '',
        }"
      >
        <template v-if="data.locked == 1">
          <i class="iconfont icon-lock"></i>
          <span>预览</span>
        </template>
        <template v-else-if="data.locked == 2">
          <i class="iconfont icon-suoding"></i>
          <span>锁定</span>
        </template>
        <template v-else>
          <i class="iconfont icon-unlock"></i>
          <span>编辑</span>
        </template>
      </a>
      <a @click="onView()" title="运行查看">
        <t-icon name="play-circle" />
        <span>预览</span>
      </a>
      <template v-if="scale > 0">
        <a>
          <span style="line-height: 40px">{{ scale }}%</span>
          <span>视图</span>
        </a>
      </template>
      <a-tooltip title="100%视图" placement="bottom">
        <a @click="onScaleDefault">
          <t-icon name="refresh" />
        </a>
      </a-tooltip>
      <a @click="onScaleWindow" title="窗口大小">
        <t-icon name="fullscreen-exit" />
        <span>窗口大小</span>
      </a>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { Icon } from "tdesign-vue-next";
// import { GithubOutlined } from "@ant-design/icons-vue";
export default defineComponent({
  components: {
    // GithubOutlined,
    "t-icon": Icon,
  },
});
</script>

<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Pen, PenType, deepClone } from '@meta2d/core';
// @ts-ignore
import FileSaver from 'file-saver';
import { MessagePlugin } from 'tdesign-vue-next';
import { CaretDownOutlined } from '@ant-design/icons-vue';


const router = useRouter();
let data = ref<any>({});

const assets = reactive({
  home: 'https://le5le.com',
  helps: [
    {
      name: '产品介绍',
      url: 'https://doc.le5le.com/document/118756411',
    },
    {
      name: '快速上手',
      url: 'https://doc.le5le.com/document/119363000',
    },
    {
      name: '使用手册',
      url: 'https://doc.le5le.com/document/118764244',
    },
    {
      name: '快捷键',
      url: 'https://doc.le5le.com/document/119620214',
      divider: true,
    },
    {
      name: '企业服务与支持',
      url: 'https://doc.le5le.com/document/119296274',
      divider: true,
    },
    {
      name: '关于我们',
      url: 'https://le5le.com/about.html',
    },
  ],
});

const isDrawLine = ref<boolean>(false);

const scale = ref(0);
const lockState = ref<number>(0)

let isOnDrawLine = ref(false);
let isDrawingPencil = ref<boolean>(false);
let isShowMagnifier = ref<boolean>(false);
let lineWidthVisible = ref(false);
let isAutoAnchor = ref<boolean>(false); //连线时，自动选中节点锚点
let isDisableAnchor = ref<boolean>(false); //禁止显示锚点

onMounted(() => {
  const timer = setInterval(() => {
    if (meta2d) {
      console.log("data", meta2d.store.data);
      data.value = meta2d.store.data;
      console.log('data', data.value);
      if (meta2d.store.data["lineWidth"] == undefined) {
        meta2d.store.data["lineWidth"] = 1;
        meta2d.setValue({
          lineWidth: 1,
        });
      }
      clearInterval(timer);
      // 获取初始缩放比例
      scaleSubscriber(meta2d.store.data.scale);

      // 监听缩放
      // @ts-ignore
      meta2d.on('scale', scaleSubscriber);
    }
  }, 200);
});

const scaleSubscriber = (val: number) => {
  scale.value = Math.round(val * 100);
};

const drawLine = () => {
  if (isDrawLine.value) {
    isDrawLine.value = false;
    meta2d.finishDrawLine();
    meta2d.drawLine();
    meta2d.store.options.disableAnchor = true;
  } else {
    isDrawLine.value = true;
    meta2d.drawLine(meta2d.store.options.drawingLineName);
    meta2d.store.options.disableAnchor = false;
  }
};

const lineTypes = reactive([
  { name: '曲线', icon: '#l-curve2', value: 'curve' },
  { name: '线段', icon: '#l-polyline', value: 'polyline' },
  { name: '直线', icon: '#l-line', value: 'line' },
  { name: '脑图曲线', icon: '#l-mind', value: 'mind' },
]);
const currentLineType = ref('curve');

const changeLineType = (value: string) => {
  currentLineType.value = value;
  if (meta2d) {
    meta2d.store.options.drawingLineName = value;
    meta2d.canvas.drawingLineName && (meta2d.canvas.drawingLineName = value);
    meta2d.store.active?.forEach((pen) => {
      meta2d.updateLineType(pen, value);
    });
  }
};

const fromArrow = ref('');
const fromArrows = [
  { icon: '#l-line', value: '' },
  { icon: '#l-from-triangle', value: 'triangle' },
  { icon: '#l-from-diamond', value: 'diamond' },
  { icon: '#l-from-circle', value: 'circle' },
  { icon: '#l-from-lineDown', value: 'lineDown' },
  { icon: '#l-from-lineUp', value: 'lineUp' },
  { icon: '#l-from-triangleSolid', value: 'triangleSolid' },
  { icon: '#l-from-diamondSolid', value: 'diamondSolid' },
  { icon: '#l-from-circleSolid', value: 'circleSolid' },
  { icon: '#l-from-line', value: 'line' },
];
const toArrow = ref('');
const toArrows = [
  { icon: '#l-line', value: '' },
  { icon: '#l-to-triangle', value: 'triangle' },
  { icon: '#l-to-diamond', value: 'diamond' },
  { icon: '#l-to-circle', value: 'circle' },
  { icon: '#l-to-lineDown', value: 'lineDown' },
  { icon: '#l-to-lineUp', value: 'lineUp' },
  { icon: '#l-to-triangleSolid', value: 'triangleSolid' },
  { icon: '#l-to-diamondSolid', value: 'diamondSolid' },
  { icon: '#l-to-circleSolid', value: 'circleSolid' },
  { icon: '#l-to-line', value: 'line' },
];

const changeFromArrow = (value: string) => {
  fromArrow.value = value;
  // 画布默认值
  meta2d.store.data.fromArrow = value;
  // 活动层的箭头都变化
  if (meta2d.store.active) {
    meta2d.store.active.forEach((pen: Pen) => {
      if (pen.type === PenType.Line) {
        pen.fromArrow = value;
        meta2d.setValue(
          {
            id: pen.id,
            fromArrow: pen.fromArrow,
          },
          {
            render: false,
          }
        );
      }
    });
    meta2d.render();
  }
};

const changeToArrow = (value: string) => {
  toArrow.value = value;
  // 画布默认值
  meta2d.store.data.toArrow = value;
  // 活动层的箭头都变化
  if (meta2d.store.active) {
    meta2d.store.active.forEach((pen: Pen) => {
      if (pen.type === PenType.Line) {
        pen.toArrow = value;
        meta2d.setValue(
          {
            id: pen.id,
            toArrow: pen.toArrow,
          },
          {
            render: false,
          }
        );
      }
    });
    meta2d.render();
  }
};



function readFile(file: Blob) {
  return new Promise<string>((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      resolve(reader.result as string);
    };
    reader.onerror = reject;
    reader.readAsText(file);
  });
}

const handleClickChangeLockFun = (status:number) => {
  console.log('status', status)
  meta2d.lock(status);
  lockState.value = status;
}



// 判断该画笔 是否是组合为状态中 展示的画笔
function isShowChild(pen: any, store: any) {
  let selfPen = pen;
  while (selfPen && selfPen.parentId) {
    const oldPen = selfPen;
    selfPen = store.pens[selfPen.parentId];
    const showChildIndex = selfPen?.calculative?.showChild;
    if (showChildIndex != undefined) {
      const showChildId = selfPen.children[showChildIndex];
      if (showChildId !== oldPen.id) {
        return false;
      }
    }
  }
  return true;
}





const onCut = () => {
  meta2d.cut();
};

const onCopy = () => {
  meta2d.copy();
};

const onPaste = () => {
  meta2d.paste();
};

const onAll = () => {
  meta2d.activeAll();
};

const onDelete = () => {
  meta2d.delete();
};

const onAddShape = (event: DragEvent | MouseEvent, name: string) => {
  event.stopPropagation();
  let data: any;
  if (name === 'text') {
    // 构建一个文本图元
    data = {
      text: 'text',
      width: 100,
      height: 20,
      name: 'text',
    };
  } else if (name === 'line') {
    // 构建一个直线图元
    data = {
      anchors: [
        { id: '0', x: 1, y: 0 },
        { id: '1', x: 0, y: 1 },
      ],
      width: 100,
      height: 100,
      name: 'line',
      lineName: 'line',
      type: 1,
    };
  }
  if (!(event as DragEvent).dataTransfer) {
    // 支持点击画布添加
    meta2d.canvas.addCaches = deepClone([data]);
  } else {
    // 支持拖拽添加
    (event as DragEvent).dataTransfer?.setData('Meta2d', JSON.stringify(data));
  }
};








/**
 * 新建文件
 */
const newFile = () => {
  meta2d.open({ name: '新建项目', pens: [] } as any);
};

/**
 * 打开文件
 */
const openFile = () => {
  // 1. 显示选择文件对话框
  const input = document.createElement('input');
  input.type = 'file';
  input.onchange = async (event) => {
    const elem = event.target as HTMLInputElement;
    if (elem.files && elem.files[0]) {
      // 2. 读取文件字符串内容
      const text = await readFile(elem.files[0]);
      try {
        // 3. 打开文件内容
        meta2d.open(JSON.parse(text));
        // 可选：缩放到窗口大小展示
        meta2d.fitView();
      } catch (e) {
        console.log(e);
      }
    }
  };
  input.click();
};

/**
 * 下载JSON文件
 */
const downloadJson = () => {
  const data: any = meta2d.data();
  FileSaver.saveAs(
    new Blob([JSON.stringify(data)], {
      type: 'text/plain;charset=utf-8',
    }),
    `${data.name || 'le5le.meta2d'}.json`
  );
};

/**
 * 下载PNG文件
 */
const downloadPng = () => {
  let name = (meta2d.store.data as any).name;
  if (name) {
    name += '.png';
  }
  meta2d.downloadPng(name);
};

/**
 * 下载SVG文件
 */
const downloadSvg = () => {
  if (!C2S) {
    MessagePlugin.error('请先加载乐吾乐官网下的canvas2svg.js');
    return;
  }

  const rect: any = meta2d.getRect();
  rect.x -= 10;
  rect.y -= 10;
  const ctx = new C2S(rect.width + 20, rect.height + 20);
  ctx.textBaseline = 'middle';
  for (const pen of meta2d.store.data.pens) {
    if (pen.visible == false || !isShowChild(pen, meta2d.store)) {
      continue;
    }
    meta2d.renderPenRaw(ctx, pen, rect);
  }

  let mySerializedSVG = ctx.getSerializedSvg();
  if (meta2d.store.data.background) {
    mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
    mySerializedSVG = mySerializedSVG.replace(
      '{{bkRect}}',
      `<rect x="0" y="0" width="100%" height="100%" fill="${meta2d.store.data.background}"></rect>`
    );
  } else {
    mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
    mySerializedSVG = mySerializedSVG.replace('{{bkRect}}', '');
  }

  mySerializedSVG = mySerializedSVG.replace(/--le5le--/g, '&#x');

  const urlObject: any = (window as any).URL || window;
  const export_blob = new Blob([mySerializedSVG]);
  const url = urlObject.createObjectURL(export_blob);

  const a = document.createElement('a');
  a.setAttribute(
    'download',
    `${(meta2d.store.data as any).name || 'le5le.meta2d'}.svg`
  );
  a.setAttribute('href', url);
  const evt = document.createEvent('MouseEvents');
  evt.initEvent('click', true, true);
  a.dispatchEvent(evt);
};

/**
 * 保存文件
 */
const onSave = (flag: boolean) => {
  // 本地存储
  const data: any = meta2d.data();
  localStorage.setItem("meta2d", JSON.stringify(data));
  if (flag) {
    MessagePlugin.success("保存成功");
  }
}

/**
 * 钢笔绘制线条
 */
const onDrawLine = () => {
  if (!isOnDrawLine.value) {
    // 开始绘画：curve。除了curve，还有polyline、line、mind
    meta2d.drawLine("curve");
    isOnDrawLine.value = true;
  } else {
    // 手动完成绘画
    meta2d.finishDrawLine();
    isOnDrawLine.value = false;
  }
}

/**
 * 绘制铅笔
 */
const onDrawingPencil = () => {
  if (!isDrawingPencil.value) {
    meta2d.drawingPencil();
    isDrawingPencil.value = true;
  } else {
    meta2d.stopPencil();
    isDrawingPencil.value = false;
  }
}

/**
 * 开启或关闭放大镜
 */
const onShowMagnifier = () => {
  if (!isShowMagnifier.value) {
    meta2d.showMagnifier();
    isShowMagnifier.value = true;
  } else {
    meta2d.hideMagnifier();
    isShowMagnifier.value = false;
  }
}

/**
 * 撤销
 */
const onUndo = () => {
  meta2d.undo();
};

/**
 * 重做
 */
const onRedo = () => {
  meta2d.redo();
};

/**
 * 获取线宽
 */
const getDataLineWidth = () => {
  if (data.value["lineWidth"]) {
    meta2d.setValue({
      lineWidth: data.value.lineWidth,
    });
    // useCommonStoreWithOut().setTopology(meta2d);
  }
}

/**
 * 连线时，自动选中节点锚点
 */
const onAutoAnchor = () => {
  if (!isAutoAnchor.value) {
    meta2d.setOptions({
      autoAnchor: true,
    });
    isAutoAnchor.value = true;
  } else {
    meta2d.setOptions({
      autoAnchor: false,
    });
    isAutoAnchor.value = false;
  }
}

/**
 * 禁止显示锚点
 */
const onDisableAnchor = () => {
  if (!isDisableAnchor.value) {
    meta2d.setOptions({
      disableAnchor: true,
    });
    isDisableAnchor.value = true;
  } else {
    meta2d.setOptions({
      disableAnchor: false,
    });
    isDisableAnchor.value = false;
  }
}

/**
 * 操作画布锁定
 */
function setLocked() {
  let { locked } = data.value;
  let key = 0;
  switch (locked) {
    case 0:
      key = 1;
      break;
    case 1:
      key = 2;
      break;
    case 2:
      key = 0;
      break;
  }
  data.value.locked = key; //meta2d.store.data;
  onSave(false);
}

/**
 * 预览
 */
const onView = () => {
  // 先停止动画，避免数据波动
  meta2d.stopAnimate();
  onSave(true);
  // 跳转到预览页面
  router.push({
    path: '/preview',
    query: {
      r: Date.now() + '',
      id: data.value._id,
    },
  });
};

/**
 * 窗口100%
 */
const onScaleDefault = () => {
  meta2d.scale(1);
  meta2d.centerView();
};

/**
 * 窗口大小
 */
const onScaleWindow = () => {
  meta2d.fitView();
};

/**
 * 打开素材库
 */
// function openFileManager() {
//   let fileManager = proxy.$refs.fileManager;
//   fileManager.visible = true;
//   nextTick(() => {
//     fileManager.initMaterialFolder().then((res) => {
//       fileManager.selectedKeys = [res];
//       fileManager.queryParam.parent_id = res;
//       fileManager.init();
//     });
//   });
// }

/**
 * 分享
 */
// function onSearch() {
//   proxy.$refs.shareModal.visible = true;
// }
</script>


<style lang="scss" scoped>
.app-header {
  display: flex;
  height: 40px;
  padding: 0 12px;
  position: relative;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  border-bottom: 1px solid #dddddd;
  z-index: 3;
  justify-content: space-between;

  .head-left {
    display: flex;
    align-items: center;
  }
  .head-center {
    display: flex;
  }
  .head-right {
    display: flex;
    align-items: center;
  }

  a {
    color: #595959;
    font-size: 14px;
    display: flex;
    margin: 0 8px;
    align-items: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;

    &:hover {
      color: #4583ff;
    }

    svg {
      font-size: 15px;
      margin: 2px 4px 0 0;
    }

    &.active {
      background-color: #0c56eb;
      color: #ffffff;
    }
  }

  .logo {
    display: flex;
    align-items: center;
    font-size: 14px;
    font-weight: 500;
    padding-left: 0;

    img {
      height: 20px;
      margin-right: 6px;
    }
  }



  svg {
    height: 40px;
    margin: 0 8px;
    &:hover {
      color: #4583ff;
      cursor: pointer;
    }
  }
  .icon-a-56px_line_Anti-fraud:before {
    font-size: 18px;
  }
}
</style>

<style>
.t-dropdown__item-text {
  a {
    color: #595959;
    text-decoration: none;
    white-space: nowrap;

    &:hover {
      color: #4583ff;
    }
  }
}
</style>